

#include <pcap.h>
#include <time.h>
#include <stdio.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <linux/if_ether.h>
#include <linux/ip.h>

void pcap_get(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
    if (user != NULL)
    {
        // printf("Device name: %s\n", user);
    }

    struct ethhdr *eth_header = (struct ethhdr *)bytes;
#if 0
    printf("Packet length: %d\n", h->len);
    printf("Number of bytes: %d\n", h->caplen);
    printf("Recieved time: %s\n", ctime((const time_t *)&h->ts.tv_sec));

    
    printf("dest mac: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
           eth_header->h_dest[0], eth_header->h_dest[1], eth_header->h_dest[2],
           eth_header->h_dest[3], eth_header->h_dest[4], eth_header->h_dest[5]);

    printf("src mac: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
           eth_header->h_source[0], eth_header->h_source[1], eth_header->h_source[2],
           eth_header->h_source[3], eth_header->h_source[4], eth_header->h_source[5]);
#endif
    switch (htons(eth_header->h_proto))
    {
    case ETH_P_IP:
        printf("Internet Protocol packet\n");
        struct iphdr *ip_header = (struct iphdr *)(bytes + sizeof(struct ethhdr));

        struct in_addr addr;
        memcpy(&addr, &ip_header->saddr, sizeof(ip_header->saddr));
        printf("source ip: %s\n", inet_ntoa(addr));

        memcpy(&addr, &ip_header->daddr, sizeof(ip_header->daddr));
        printf("dest ip: %s\n", inet_ntoa(addr));
        break;

    default:
        printf("%04X\n", eth_header->h_proto);
        break;
    }
}

int main()
{

    char errbuf[PCAP_ERRBUF_SIZE];

    pcap_t *device = pcap_open_live("eth0", 1518, 1, 0, errbuf);

    if (device == NULL)
    {
        printf("Failure!\n");
        return -1;
    }

    pcap_loop(device, -1, pcap_get, "eth0");

    pcap_close(device);

    return 0;
}